package com.senlingspace.system.service.impl;

import com.senlingspace.common.enums.LakalaTradeStateEnum;
import com.senlingspace.common.enums.RelatedType;
import com.senlingspace.common.utils.DateUtils;
import com.senlingspace.common.utils.MoneyUtils;
import com.senlingspace.system.domain.SlkjTicketCategory;
import com.senlingspace.system.domain.dto.TicketIncomeDTO;
import com.senlingspace.system.domain.vo.TicketIncomeVo;
import com.senlingspace.system.mapper.*;
import com.senlingspace.system.service.TicketIncomeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author Administrator
 */
@Service
public class TicketIncomeServiceImpl implements TicketIncomeService {
    @Autowired
    private  SlkjOrderMapper slkjOrderMapper;
    @Autowired
    private SlkjTicketCategoryMapper slkjTicketCategoryMapper;

    @Override
    public List<TicketIncomeVo> selectTicketIncomeList(Date startTime, Date endTime,Long shopId, Long ticketId) {
        // 如果 startTime 和 endTime 为 null，则设置为今天的初始时间和结束时间
        if (startTime == null) {
            startTime = DateUtils.getStartOfDay(new Date());
        }else {
            startTime = DateUtils.getStartOfDay(startTime);
        }
        if(endTime == null ){
            endTime = DateUtils.getStartOfDay(new Date());
        }else {
            endTime = DateUtils.getStartOfDay(endTime);
        }

        List<TicketIncomeDTO> ticketIncomeDTOS = slkjOrderMapper.selectOrderList(startTime, endTime, shopId, ticketId);

        // 处理数据
        Map<String, Map<Long, Map<String, Map<String, Long>>>> result = ticketIncomeDTOS.stream()
                .collect(Collectors.groupingBy(
                        TicketIncomeDTO::getShopId,
                        Collectors.groupingBy(
                                TicketIncomeDTO::getTicketCategoryId,
                                Collectors.groupingBy(
                                        TicketIncomeDTO::getPaymentStatus,
                                        Collectors.groupingBy(
                                                TicketIncomeDTO::getRelatedType,
                                                Collectors.summingLong(TicketIncomeDTO::getProfitShareAmount)
                                        )
                                )
                        )
                ));

        // 先按 orderId 和 ticketCategoryId 进行分组，然后取每个分组的第一条记录
        List<TicketIncomeDTO> uniqueRecords = ticketIncomeDTOS.stream()
                .collect(Collectors.toMap(
                        dto -> dto.getOrderId() + "_" + dto.getTicketCategoryId(),
                        dto -> dto,
                        (existing, replacement) -> existing
                ))
                .values()
                .stream()
                .collect(Collectors.toList());

        // 按照 ticketCategoryId 进行分组，并计算每个分组的 bayQuantity 总和
        Map<Long, Long> bayQuantitySum = uniqueRecords.stream()
                .collect(Collectors.groupingBy(
                        TicketIncomeDTO::getTicketCategoryId,
                        Collectors.summingLong(TicketIncomeDTO::getBayQuantity)
                ));

        // 获取到销售额
        Map<Long, Long> userActualAmountSum = uniqueRecords.stream()
                .collect(
                        Collectors.groupingBy(
                                TicketIncomeDTO::getTicketCategoryId,
                                Collectors.summingLong(TicketIncomeDTO::getUserActualAmount)
                        )
                );

        // 获取到退款的数据
        List<TicketIncomeDTO> refundRecords = ticketIncomeDTOS.stream()
                .filter(dto -> LakalaTradeStateEnum.REFUND.name().equals(dto.getPaymentStatus()))
                .collect(Collectors.toList());

        // 对退款数据进行去重
        List<TicketIncomeDTO> uniqueRefundRecords = refundRecords.stream()
                .collect(Collectors.toMap(
                        dto -> dto.getOrderId() + "_" + dto.getTicketCategoryId(),
                        dto -> dto,
                        (existing, replacement) -> existing
                ))
                .values()
                .stream()
                .collect(Collectors.toList());

        // 按照 ticketCategoryId 进行分组，并计算每个分组的 bayQuantity 和 userActualAmount 总和
        Map<Long, Long> refundBayQuantitySum = uniqueRefundRecords.stream()
                .collect(Collectors.groupingBy(
                        TicketIncomeDTO::getTicketCategoryId,
                        Collectors.summingLong(TicketIncomeDTO::getBayQuantity)
                ));

        Map<Long, Long> refundUserActualAmountSum = uniqueRefundRecords.stream()
                .collect(
                        Collectors.groupingBy(
                                TicketIncomeDTO::getTicketCategoryId,
                                Collectors.summingLong(TicketIncomeDTO::getUserActualAmount)
                        )
                );

        List<TicketIncomeVo> ticketIncomeVos = new ArrayList<>();

        for (Map.Entry<String, Map<Long, Map<String, Map<String, Long>>>> shopEntry : result.entrySet()) {
            String shopIdStr = shopEntry.getKey();
            String shopName = null;
            for (TicketIncomeDTO dto : ticketIncomeDTOS) {
                if (dto.getShopId().equals(shopIdStr)) {
                    shopName = dto.getShopName();
                    break;
                }
            }

            for (Map.Entry<Long, Map<String, Map<String, Long>>> categoryEntry : shopEntry.getValue().entrySet()) {
                Long ticketCategoryId = categoryEntry.getKey();
                String ticketCategoryName = null;
                for (TicketIncomeDTO dto : ticketIncomeDTOS) {
                    if (dto.getTicketCategoryId().equals(ticketCategoryId)) {
                        ticketCategoryName = dto.getTicketCategoryName();
                        break;
                    }
                }

                // 处理 paymentStatus 为 SUCCESS 和 REFUND 的数据
                for (String paymentStatus : Arrays.asList("SUCCESS", "REFUND")) {
                    Map<String, Long> paymentData = categoryEntry.getValue().get(paymentStatus);
                    if (paymentData != null) {
                        for (Map.Entry<String, Long> relatedTypeEntry : paymentData.entrySet()) {
                            String relatedType = relatedTypeEntry.getKey();
                            Long profitShareAmount = relatedTypeEntry.getValue();

                            TicketIncomeVo vo = new TicketIncomeVo();
                            vo.setShopId(Long.parseLong(shopIdStr));
                            vo.setShopName(shopName);
                            vo.setTicketId(ticketCategoryId);
                            vo.setTicketName(ticketCategoryName);

                            if (RelatedType.INVESTOR.getCode().equals(relatedType)) {
                                vo.setInvestor(MoneyUtils.hao2Yuan(profitShareAmount));
                            } else if (RelatedType.PROJECT.getCode().equals(relatedType)) {
                                vo.setProject(MoneyUtils.hao2Yuan(profitShareAmount));
                            } else if (RelatedType.OPERATION.getCode().equals(relatedType)) {
                                vo.setOperation(MoneyUtils.hao2Yuan(profitShareAmount));
                            } else if (RelatedType.TICKET_SYSTEM.getCode().equals(relatedType)) {
                                vo.setTicket(MoneyUtils.hao2Yuan(profitShareAmount));
                            }

                            // 判断 bayQuantitySum 中是否存在该 ticketCategoryId，如果存在则取 bayQuantitySum 中的值，否则取 0
                            Long bayQuantity = bayQuantitySum.getOrDefault(ticketCategoryId, 0L);
                            vo.setTicketQuantity(bayQuantity);

                            SlkjTicketCategory slkjTicketCategory = slkjTicketCategoryMapper.selectSlkjTicketCategoryById(ticketCategoryId);
                            vo.setTicketTotal(slkjTicketCategory.getQuantity() * bayQuantity);

                            // 获取总金额
                            Long totalAmount = userActualAmountSum.getOrDefault(ticketCategoryId, 0L);
                            vo.setTotalAmount(MoneyUtils.fen2Yuan(totalAmount));

                            // 获取退款数量
                            Long refundQuantity = refundBayQuantitySum.getOrDefault(ticketCategoryId, 0L);
                            vo.setRefundQuantity(refundQuantity * slkjTicketCategory.getQuantity());

                            // 获取退款金额
                            Long refundAmount = refundUserActualAmountSum.getOrDefault(ticketCategoryId, 0L);
                            vo.setRefundAmount(MoneyUtils.fen2Yuan(refundAmount));

                            ticketIncomeVos.add(vo);
                        }
                    }
                }
            }
        }

        // 合并相同 ticketId 的数据
        Map<Long, TicketIncomeVo> mergedVos = new HashMap<>();
        for (TicketIncomeVo vo : ticketIncomeVos) {
            Long id = vo.getTicketId();
            if (!mergedVos.containsKey(id)) {
                mergedVos.put(id, vo);
            } else {
                TicketIncomeVo existingVo = mergedVos.get(id);
                existingVo.setInvestor(mergeAmount(existingVo.getInvestor(), vo.getInvestor()));
                existingVo.setProject(mergeAmount(existingVo.getProject(), vo.getProject()));
                existingVo.setOperation(mergeAmount(existingVo.getOperation(), vo.getOperation()));
                existingVo.setTicket(mergeAmount(existingVo.getTicket(), vo.getTicket()));
            }
        }

        return new ArrayList<>(mergedVos.values());
    }

    private String mergeAmount(String existingAmount, String newAmount) {
        if (existingAmount == null) {
            return newAmount;
        }
        if (newAmount == null) {
            return existingAmount;
        }
        double existingValue = Double.parseDouble(existingAmount);
        double newValue = Double.parseDouble(newAmount);
        return String.valueOf(existingValue + newValue);
    }
}